#include "ModelsManager.h"
#include "Model3D.h"
#include "ModelAnimation.h"
#include "ModelPosture.h"
#include "ModelPostureLink.h"

#include <tinyxml.h>

ModelsManager* ModelsManager::mInstance = NULL;

ModelsManager::ModelsManager()
{

}

ModelsManager::ModelsManager(const ModelsManager&)
{

}

ModelsManager::~ModelsManager()
{

}

ModelsManager* ModelsManager::Instance()
{
	if(mInstance == NULL)
	{
		mInstance = new ModelsManager();
	}
	return mInstance;
}

bool ModelsManager::Initialize()
{
	TiXmlDocument doc( "Contents\\Library.xml" );
    bool loadOkay = doc.LoadFile();


	TiXmlElement* libraryElement = doc.FirstChildElement( "Library" );


	TiXmlElement* model3DElement = libraryElement->FirstChildElement( "Model3D" );
	for( model3DElement; model3DElement; model3DElement=model3DElement->NextSiblingElement("Model3D") )
	{
		Model3D* model3D = new Model3D();
		model3D->Initialize(model3DElement);
		mModels.push_back(model3D);

		mIdToModels[model3D->GetId()] = model3D;
		mPathToModels[model3D->GetPath()] = model3D;
	}

	TiXmlElement* modelAnimationElement = libraryElement->FirstChildElement( "Animation" );
	for( modelAnimationElement; modelAnimationElement; modelAnimationElement=modelAnimationElement->NextSiblingElement("Animation") )
	{
		ModelAnimation* modelAnimation = new ModelAnimation();
		modelAnimation->Initialize(modelAnimationElement);
		mModelAnimations.push_back(modelAnimation);

		int id = ::atoi(modelAnimationElement->Attribute("id"));
		mIdToModelAnimations[id] = modelAnimation;

		const char* name = modelAnimationElement->Attribute("name");
		mNameToModelAnimations[std::string(name)] = modelAnimation;
	}

	TiXmlElement* ModelPostureElement = libraryElement->FirstChildElement( "Posture" );
	for( ModelPostureElement; ModelPostureElement; ModelPostureElement=ModelPostureElement->NextSiblingElement("Posture") )
	{
		ModelPosture* position = new ModelPosture();
		position->Initialize(ModelPostureElement);
		mModelPostures.push_back(position);
		mNameToModelPostures[position->GetName()] = position;
	}

	return true;
}

void ModelsManager::Uninit()
{

}


Model3D* ModelsManager::GetModel(int pId)
{
	return mIdToModels[pId];
}

ModelAnimation* ModelsManager::GetModelAnimationByName(std::string pAnimationName)
{
	return mNameToModelAnimations[pAnimationName];
}

Model3D* ModelsManager::GetModelByPath(std::string pModelPath)
{
	return mPathToModels[pModelPath];
}

ModelPosture* ModelsManager::GetPostureByName(std::string pPostureName)
{
	std::map<std::string,ModelPosture*>::iterator postureIt = mNameToModelPostures.find(pPostureName);
	if ( postureIt == mNameToModelPostures.end() ) {
		return NULL;
	} else {
		return (*postureIt).second;
	}
}

ModelPostureLink* ModelsManager::GetModelPostureLink(std::string pPostureName, Model3D* pModel)
{
	ModelPosture* posture = GetPostureByName(pPostureName);
	if(posture == NULL) return NULL;
	ModelPostureLink* link = new ModelPostureLink();
	link->Initialize(pModel, posture);
	return link;
}